package com.gitee.ywj1352.client.exchange;

import com.gitee.ywj1352.common.YWJFrameDecoder;
import com.gitee.ywj1352.common.message.ClientOp;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * ExchangeClient to call Server
 *
 * @author wenjieyang
 */
public class NettyExchangeClient {
    public static final Logger LOGGER = LoggerFactory.getLogger(NettyExchangeClient.class);
    private EventLoopGroup clientGroup;
    private Bootstrap bootstrap;
    private Channel clientChannel;

    public NettyExchangeClient(Map<String, String> config) {
        String host = config.get("HOST");
        int port = Integer.parseInt(config.get("PORT"));
        start(host, port);
    }

    public void start(String host, int port) {
        bootstrap = new Bootstrap();
        clientGroup = new NioEventLoopGroup();

        try {
            bootstrap.group(clientGroup);
            bootstrap.channel(NioSocketChannel.class);
            bootstrap.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    // YWJ协议
                    ch.pipeline().addLast(new YWJFrameDecoder());
                    ch.pipeline().addLast(new YWJFrameDecoder());


                    //ch.pipeline().addLast();
                }
            });
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8090);
            channelFuture.sync();
            clientChannel = channelFuture.channel();
        } catch (Exception e) {
            LOGGER.error("start client has error ", e);
        }
    }

    /**
     * call server
     *
     * @return
     */
    public void execute(ClientOp clientOp) {
        clientChannel.writeAndFlush(clientOp);
    }


    public void close() {
        try {
            clientChannel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clientGroup.shutdownGracefully();
    }

}
